#include <iostream>
#include <unistd.h>
#include <cstring>
#include <cerrno>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string>

const int size = 1024;

std::string GetOtherMessage() {
    static int cnt = 0;
    std::string messageid = std::to_string(cnt);
    pid_t rid = getpid();
    std::string child_id = std::to_string(rid);
    std::string retMessage = "messageid: ";
    retMessage += messageid;
    retMessage += " my pid is ";
    retMessage += child_id;
    cnt++;
    return retMessage;
}

void SubProcessWrite(pid_t wfd) {
    std::string message = "father, I am your son! ";
    int cnt = 1;

    while (true) {
        std::string info = message + GetOtherMessage();
        write(wfd, info.c_str(), info.size());
        sleep(1);
        // char ch = 'A';
        // write(wfd, &ch, 1);
        // std::cout << cnt++ << std::endl;
    }
}

void FatherProcessRead(pid_t rfd) {
    char inbuff[size];
    while (true) {
        // sleep(500);
        int n = read(rfd, inbuff, sizeof(inbuff) - 1);
        if (n > 0) {
            inbuff[n] = '\0';
            std::cout << "father get message: " << inbuff << std::endl;
        } else if (n == 0) {
            // read的返回值等于0，说明写端已经关闭，我们读到文件结尾
            std::cout << "client quit, father get return val: " << n << " father quit too!" << std::endl;
            break;
        } else {
            std::cerr << "read error!" << std::endl;
            break;
        }
        // break;
    }
}

int main() {
    // 创建管道
    int pipefd[2];
    int n = pipe(pipefd);
    if (n != 0) {
        std::cout << "errno: " << errno << " errstring: " << strerror(errno) << std::endl;
        return 1;
    }
    // 创建出子进程
    pid_t id = fork();
    if (id == 0) {
        // 使用子进程进行写，关闭读端
        close(pipefd[0]);
        // 子进程发送信息
        SubProcessWrite(pipefd[1]);
        close(pipefd[1]);
        exit(0);

    }
    // 父进程进行读，关闭写端
    close(pipefd[1]);
    // 父进程接收信息
    FatherProcessRead(pipefd[0]);
    close(pipefd[0]);
    // 等待回收子进程
    int status;
    pid_t rid = waitpid(id, &status, 0);
    if (rid > 0) 
        std::cout << "wait child process sucess! sig exit code: " << (status & 0x7F) << std::endl;
    else
        std::cout << "wait child process fail!" << std::endl;
    return 0;
}